<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.6.6" />
<title>Release notes for Gerrit 2.0.19, 2.0.19.1, 2.0.19.2</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */

/* Default font. */
body {
  font-family: Georgia,serif;
}

/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
  font-family: Arial,Helvetica,sans-serif;
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}
h5 {
  font-size: 1.0em;
}

div.sectionbody {
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}
ul > li     { color: #aaa; }
ul > li > * { color: black; }

pre {
  padding: 0;
  margin: 0;
}

#author {
  color: #527bbd;
  font-weight: bold;
  font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}

#footer {
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid #dddddd;
  border-left: 4px solid #f0f0f0;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid #dddddd;
  border-left: 5px solid #f0f0f0;
  background: #f8f8f8;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #f0f0f0;
  color: #888;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
  font-size: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}

div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}

div.colist td {
  padding-right: 0.5em;
  padding-bottom: 0.3em;
  vertical-align: top;
}
div.colist td img {
  margin-top: 0.3em;
}

@media print {
  #footer-badges { display: none; }
}

#toc {
  margin-bottom: 2.5em;
}

#toctitle {
  color: #527bbd;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}

span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }

span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }

span.big { font-size: 2em; }
span.small { font-size: 0.6em; }

span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }


/*
 * xhtml11 specific
 *
 * */

tt {
  font-family: monospace;
  font-size: inherit;
  color: navy;
}

div.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-weight: bold;
  color: #527bbd;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


/*
 * html5 specific
 *
 * */

.monospaced {
  font-family: monospace;
  font-size: inherit;
  color: navy;
}

table.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
thead, p.tableblock.header {
  font-weight: bold;
  color: #527bbd;
}
p.tableblock {
  margin-top: 0;
}
table.tableblock {
  border-width: 3px;
  border-spacing: 0px;
  border-style: solid;
  border-color: #527bbd;
  border-collapse: collapse;
}
th.tableblock, td.tableblock {
  border-width: 1px;
  padding: 4px;
  border-style: solid;
  border-color: #527bbd;
}

table.tableblock.frame-topbot {
  border-left-style: hidden;
  border-right-style: hidden;
}
table.tableblock.frame-sides {
  border-top-style: hidden;
  border-bottom-style: hidden;
}
table.tableblock.frame-none {
  border-style: hidden;
}

th.tableblock.halign-left, td.tableblock.halign-left {
  text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
  text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
  text-align: right;
}

th.tableblock.valign-top, td.tableblock.valign-top {
  vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
  vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
  vertical-align: bottom;
}


/*
 * manpage specific
 *
 * */

body.manpage h1 {
  padding-top: 0.5em;
  padding-bottom: 0.5em;
  border-top: 2px solid silver;
  border-bottom: 2px solid silver;
}
body.manpage h2 {
  border-style: none;
}
body.manpage div.sectionbody {
  margin-left: 3em;
}

@media print {
  body.manpage div#toc { display: none; }
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  if (!toc) {
    return;
  }

  // Delete existing TOC entries in case we're reloading the TOC.
  var tocEntriesToRemove = [];
  var i;
  for (i = 0; i < toc.childNodes.length; i++) {
    var entry = toc.childNodes[i];
    if (entry.nodeName == 'div'
     && entry.getAttribute("class")
     && entry.getAttribute("class").match(/^toclevel/))
      tocEntriesToRemove.push(entry);
  }
  for (i = 0; i < tocEntriesToRemove.length; i++) {
    toc.removeChild(tocEntriesToRemove[i]);
  }

  // Rebuild TOC entries.
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  // Delete existing footnote entries in case we're reloading the footnodes.
  var i;
  var noteholder = document.getElementById("footnotes");
  if (!noteholder) {
    return;
  }
  var entriesToRemove = [];
  for (i = 0; i < noteholder.childNodes.length; i++) {
    var entry = noteholder.childNodes[i];
    if (entry.nodeName == 'div' && entry.getAttribute("class") == "footnote")
      entriesToRemove.push(entry);
  }
  for (i = 0; i < entriesToRemove.length; i++) {
    noteholder.removeChild(entriesToRemove[i]);
  }

  // Rebuild footnote entries.
  var cont = document.getElementById("content");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      var note = spans[i].getAttribute("data-note");
      if (!note) {
        // Use [\s\S] in place of . so multi-line matches work.
        // Because JavaScript has no s (dotall) regex flag.
        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
        spans[i].innerHTML =
          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
        spans[i].setAttribute("data-note", note);
      }
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
},

install: function(toclevels) {
  var timerId;

  function reinstall() {
    asciidoc.footnotes();
    if (toclevels) {
      asciidoc.toc(toclevels);
    }
  }

  function reinstallAndRemoveTimer() {
    clearInterval(timerId);
    reinstall();
  }

  timerId = setInterval(reinstall, 500);
  if (document.addEventListener)
    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
  else
    window.onload = reinstallAndRemoveTimer;
}

}
asciidoc.install(2);
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>Release notes for Gerrit 2.0.19, 2.0.19.1, 2.0.19.2</h1>
<span id="revnumber">version 2.0.19 (from v2.7-rc2-530-g4d7ac77)</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Gerrit 2.0.19.2 is now available in the usual location:</p></div>
<div class="paragraph"><p><a href="http://code.google.com/p/gerrit/downloads/list">http://code.google.com/p/gerrit/downloads/list</a></p></div>
</div>
</div>
<div class="sect1">
<h2 id="_important_notices">Important Notices</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Prior User Sessions
</p>
<div class="paragraph"><p>The cookie used to identify a signed-in user has been changed.  All users
will be automatically signed-out during this upgrade, and will need to
sign-in again after the upgrade is complete.
Users who try to use a web session from before the upgrade may receive the
obtuse error message "Invalid xsrfKey in request".  Prior web clients are
misinterpreting the error from the server.  Users need to sign-out and
sign-in again to pick up a new session.
This change was necessary to close GERRIT-83, see below.</p></div>
</li>
<li>
<p>
Preserving Sessions Across Restarts
</p>
<div class="paragraph"><p>Administrators who wish to preserve user sessions across server restarts must
set [<a href="http://gerrit.googlecode.com/svn/documentation/2.0/config-gerrit.html#cache.directory">http://gerrit.googlecode.com/svn/documentation/2.0/config-gerrit.html#cache.directory</a> cache.directory] in gerrit.config.  This allows Gerrit to flush the set
of active sessions to disk during shutdown, and load them back during startup.</p></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_schema_change">Schema Change</h2>
<div class="sectionbody">
<div class="paragraph"><p><strong>WARNING: This version contains a schema change</strong> (since 2.0.18)</p></div>
<div class="paragraph"><p>Important notes about this schema change:</p></div>
<div class="ulist"><ul>
<li>
<p>
Do not run the schema change while the server is running.
</p>
<div class="paragraph"><p>This upgrade adds a new required column to the changes table, something
which cannot be done while users are creating records. Like .18, I <em>strongly</em>
suggest a full shutdown, schema upgrade, then startup approach.
Apply the database specific schema script:</p></div>
</li>
</ul></div>
<div class="listingblock">
<div class="content">
<pre><tt>  java -jar gerrit.war --cat sql/upgrade016_017_postgres.sql | psql reviewdb
  java -jar gerrit.war --cat sql/upgrade016_017_mysql.sql    | mysql reviewdb</tt></pre>
</div></div>
</div>
</div>
<div class="sect1">
<h2 id="_new_features">New Features</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
New ssh create-project command
</p>
<div class="paragraph"><p>Thanks to Ulrik Sjölin we now have <tt>gerrit create-project</tt>
available over SSH, to construct a new repository and database
record for a project.  Documentation has also been updated to
reflect that the command is now available.</p></div>
</li>
<li>
<p>
Be more liberal in accepting Signed-off-by lines
</p>
<div class="paragraph"><p>The "Require Signed-off-by line" feature in a project is now
more liberal.  Gerrit now requires that the commit be signed off
by either the author or the committer.  This was relaxed because
kernel developers often cherry-pick in patches signed off by
the author and by Linus Torvalds, but not by the committer who
did the backport cherry-pick.</p></div>
</li>
<li>
<p>
Allow cache.name.diskLimit = 0 to disable on disk cache
</p>
<div class="paragraph"><p>Setting cache.name.diskLimit to 0 will disable the disk for
that cache, even though cache.directory was set.  This allows
sites to set cache.diff.diskLimit to 0 to avoid caching the diff
records on disk, but still allow caching web_sessions to disk,
so that live sessions are maintained across server restarts.
This is a change in behavior, the prior meaning of diskLimit =
0 was "unlimited", which is not very sane given how Ehcache
manages the on disk cache files.</p></div>
</li>
<li>
<p>
Allow human-readable units in config.name.maxage
</p>
<div class="paragraph"><p>Timeouts for any cache.name.maxAge may now be specified in human
readable units, such as "12 days" or "3 hours".  The server will
automatically convert them to minutes during parsing.  If no
unit is specified, minutes are assumed, to retain compatibility
with prior releases.</p></div>
</li>
<li>
<p>
Add native LDAP support to Gerrit
</p>
<div class="paragraph"><p>Gerrit now has native LDAP support.  Setting auth.type to
HTTP_LDAP and then configuring the handful of ldap properties
in gerrit.config will allow Gerrit to load group membership
directly from the organization&#8217;s LDAP server.  This replaces
the need for the sync-groups script posted in the wiki.  See:
<a href="http://gerrit.googlecode.com/svn/documentation/2.0/config-gerrit.html#ldap">http://gerrit.googlecode.com/svn/documentation/2.0/config-gerrit.html#ldap</a>
If you use the sync-groups script from the wiki page, you would
also need to delete the group members after upgrading, to remove
unnecessary records in your database:
{{{
DELETE FROM account_group_members
WHERE group_id IN (
SELECT group_id FROM account_groups
WHERE automatic_membership = <em>Y</em>);
}}}</p></div>
</li>
<li>
<p>
Don&#8217;t allow users to edit their name if it comes from LDAP
</p>
<div class="paragraph"><p>User information loaded from LDAP, such as full name or SSH
username, cannot be modified by the end-user.  This allows the
Gerrit site administrator to require that users conform to the
standard information published by the organization&#8217;s directory
service.  Updates in LDAP are automatically reflected in Gerrit
the next time the user signs-in.</p></div>
</li>
<li>
<p>
Remembers anchor during HTTP logins
</p>
<div class="paragraph"><p>When using an HTTP SSO product, clicking on a Gerrit link received
out-of-band (e.g. by email or IM) often required clicking the
link twice.  On the first click Gerrit redirect you to the
organization&#8217;s single-sign-on authentication system, which upon
success redirected to your dashboard.  The actual target of the
link was often lost, so a second click was required.
With .19 and later, if the administrator changes the frontend web
server to perform authentication only for the /login/ subdirectory
of Gerrit, this can be avoided.  For example with Apache:</p></div>
</li>
</ul></div>
<div class="listingblock">
<div class="content">
<pre><tt>     &lt;Location "/login/"&gt;
       AuthType Basic
       AuthName "Gerrit Code Review"
       Require valid-user
       ...
     &lt;/Location&gt;</tt></pre>
</div></div>
<div class="literalblock">
<div class="content">
<pre><tt>During a request for an arbitrary URL, such as '/#change,42',
Gerrit realizes the user is not logged in.  Instead of sending an
immediate redirect for authentication, Gerrit sends JavaScript
to save the target token (the part after the '#' in the URL)
by redirecting the user to '/login/change,42'.  This enters
the secured area, and performs the authentication.  When the
authenticated user returns to '/login/change,42' Gerrit sends
a redirect back to the original URL, '/#change,42'.</tt></pre>
</div></div>
<div class="ulist"><ul>
<li>
<p>
Create check_schema_version during schema creation
</p>
<div class="paragraph"><p>Schema upgrades for PostgreSQL now validate that the current
schema version matches the expected schema version at the start
of the upgrade script.  If the schema does not match, the script
aborts, although it will spew many errors.</p></div>
</li>
<li>
<p>
Reject disconnected ancestries when creating changes
</p>
<div class="paragraph"><p>Uploading commits to a project now requires that the new commits
share a common ancestry with the existing commits of that project.
This catches and prevents problems caused by a user making a typo
in the project name, and inadvertently selecting the wrong project.</p></div>
</li>
<li>
<p>
Change-Id tags in commit messages to associate commits
</p>
<div class="paragraph"><p>Gerrit now looks for <em>Change-Id: I&#8230;.</em> in the footer area of a
commit message and uses this to identify a change record within
the project.
If the listed Change-Id has not been seen before, a new change
record is created.  If the Change-Id is already known, Gerrit
updates the change with the new commit.  This simplifies updating
multiple changes at once, such as might happen when rebasing an
entire series of commits that are still being reviewed.
A commit-msg hook can be installed to automatically generate
these Change-Id lines during initial commit:
{{{
scp -P 29418 review.example.com:hooks/commit-msg .git/hooks/
}}}
Using this hook ensures that the Change-Id is predicatable once
the commit is uploaded for review.
For more details, please see the docs:
<a href="http://gerrit.googlecode.com/svn/documentation/2.0/user-changeid.html">http://gerrit.googlecode.com/svn/documentation/2.0/user-changeid.html</a></p></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_bug_fixes">Bug Fixes</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Fix yet another ArrayIndexOutOfBounds during side-by-s&#8230;
</p>
<div class="paragraph"><p>We found yet another bug with the side-by-side view failing
under certain conditions.  I think this is the last bug.</p></div>
</li>
<li>
<p>
Apply URL decoding to parameter of /cat/
</p>
</li>
<li>
<p>
Fix old image when shown inline in unified diff
</p>
<div class="paragraph"><p>Images weren&#8217;t displaying correctly, even though
mimetype.image/png.safe was true in gerrit.config.
Turned out to be a problem with the parameter decoding of the
/cat/ servlet, as well as the link being generated wrong.</p></div>
</li>
<li>
<p>
Fix high memory usage seen in <tt>gerrit show-caches</tt>
</p>
<div class="paragraph"><p>In Gerrit 2.0.18 JGit had a bug where the repository wasn&#8217;t being
reused in memory.  This meant that we were constantly reloading
the repository data in from disk, so the server was always maxed
out at core.packedGitLimit and core.packedGitOpenFiles, as no
data was being reused from the cache.  Fixed in this release.</p></div>
</li>
<li>
<p>
Fix display of timeouts in <tt>gerrit show-caches</tt>
</p>
<div class="paragraph"><p>Timeouts were not always shown correctly, sometimes 12 hours
was showing up as 2.5 days, which is completely wrong.  Fixed.</p></div>
</li>
<li>
<p>
GERRIT-261  Fix reply button when comment is on the last line
</p>
<div class="paragraph"><p>The "Reply" button didn&#8217;t work if the comment was on the last
line of the file, the browser caught an array index out of
bounds exception as we walked off the end of the table looking
for where to insert the new editor box.</p></div>
</li>
<li>
<p>
GERRIT-83   Make sign-out really invalidate the user&#8217;s session
</p>
<div class="paragraph"><p>The sign-out link now does more than delete the cookie from the
user&#8217;s browser, it also removes the token from the server side.
By removing it from the server, we prevent replay attacks where
an attacker has observed the user&#8217;s cookie and then later tries
to issue their own requests with the user&#8217;s cookie.  Note that
this sort of attack is difficult if SSL is used, as the attacker
would have a much more difficult time of sniffing the user&#8217;s
cookie while it was still live.</p></div>
</li>
<li>
<p>
Evict account record after changing SSH username
</p>
<div class="paragraph"><p>Changing the SSH username on the web immediately affected the
SSH daemon, but the web still showed the old username.  This
was due to the change operation not flushing the cache that
the web code was displaying from.  Fixed.</p></div>
</li>
<li>
<p>
Really don&#8217;t allow commits to replace in wrong project
</p>
<div class="paragraph"><p>It was possible for users to upload replacement commits to the
wrong project, e.g. uploading a replacement commit to project
B while picking a change number from project A.  Fixed.</p></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_fixes_in_2_0_19_1">=Fixes in 2.0.19.1=</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Fix NPE during direct push to branch closing a change
</p>
<div class="paragraph"><p>Closing changes by pushing their commits directly into the branch didn&#8217;t
always work as expected, due to some data not being initialized correctly.</p></div>
</li>
<li>
<p>
Ignore harmless "Pipe closed" in scp command
</p>
<div class="paragraph"><p>scp command on the server side threw exceptions when a client aborted the
data transfer.  We typically don&#8217;t care to log such cases.</p></div>
</li>
<li>
<p>
Refactor user lookup during permission checking
</p>
</li>
<li>
<p>
GERRIT-264  Fix membership in Registered Users group
</p>
<div class="paragraph"><p>Users were not a member of "Registered Users", this was a rather serious
bug in the code as it meant many users lost their access rights.</p></div>
</li>
<li>
<p>
GERRIT-265  Correctly catch "Invalid xsrfKey in request" error as &#8230;
</p>
<div class="paragraph"><p>Above I mentioned we should handle this error as "Not Signed In", only
the pattern match wasn&#8217;t quite right.  Fixed.</p></div>
</li>
<li>
<p>
GERRIT-263  Fix --re=bob to match <a href="mailto:bob@example.com">bob@example.com</a> when using HTTP_LDAP
</p>
<div class="paragraph"><p>HTTP_LDAP broke using local usernames to match an account.  Fixed.</p></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_fixes_in_2_0_19_2">=Fixes in 2.0.19.2=</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Don&#8217;t line wrap project or group names in admin panels
</p>
<div class="paragraph"><p>Line wrapping group names like "All Users" when the description column
has a very long name in it is ugly.</p></div>
</li>
<li>
<p>
GERRIT-267  Don&#8217;t add users to a change review if they cannot access
</p>
<div class="paragraph"><p>If a user cannot access a change, let the owner know when they try to
add the user as a reviewer, or CC them on it.</p></div>
</li>
<li>
<p>
commit-msg: Do not insert Change-Id if the message is &#8230;
</p>
<div class="paragraph"><p>The commit-msg hook didn&#8217;t allow users to abort accidental git commit
invocations, as it still modified the file, making git commit think
that the end-user wanted to make a commit.  Anyone who has a copy of
the hook should upgrade to the new hook, if possible.</p></div>
</li>
<li>
<p>
Support recursive queries against LDAP directories
</p>
</li>
<li>
<p>
Fix parsing of LDAP search scope properties
</p>
<div class="paragraph"><p>As reported on repo-discuss, recursive search is sometimes necessary,
and is now the default.</p></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_removed_features">Removed Features</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Remove support for /user/email style URLs
</p>
<div class="paragraph"><p>I decided to remove this URL, its a pain to support and not
discoverable.  Its unlikely anyone is really using it, but if
they are, they could try using "#q,owner:email,n,z" instead.</p></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_other_changes">Other Changes</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Start 2.0.19 development
</p>
</li>
<li>
<p>
Document the Failure and UnloggedFailure classes in Ba&#8230;
</p>
</li>
<li>
<p>
Merge change 11109
</p>
</li>
<li>
<p>
Document gerrit receive-pack is alias for git receive-&#8230;
</p>
</li>
<li>
<p>
Define a simple query language for Gerrit
</p>
</li>
<li>
<p>
Create new projects on remote systems with mkdir -p
</p>
</li>
<li>
<p>
Set the GIT_DIR/description file during gerrit create-&#8230;
</p>
</li>
<li>
<p>
Remove unnecessary toLowerCase calls in AdminCreatePro&#8230;
</p>
</li>
<li>
<p>
Remove unnecessary exception from AdminCreateProject
</p>
</li>
<li>
<p>
Remove unused import from AccountExternalId
</p>
</li>
<li>
<p>
Abstract out account creation and simplify sign-on for&#8230;
</p>
</li>
<li>
<p>
Implement server side sign-out handling
</p>
</li>
<li>
<p>
Cleanup private keys in system_config table
</p>
</li>
<li>
<p>
Remove dead max_session_age field from system_config
</p>
</li>
<li>
<p>
Report <em>Invalid xsrfKey</em> as <em>Not Signed In</em>
</p>
</li>
<li>
<p>
Update gerrit flush-caches documentation about web_ses&#8230;
</p>
</li>
<li>
<p>
Update documentation on cache "web_sessions" configura&#8230;
</p>
</li>
<li>
<p>
Add getSchemeRest to AccountExternalId
</p>
</li>
<li>
<p>
Cleanup ContactStore and WebModule injection
</p>
</li>
<li>
<p>
Catch Bouncy Castle Crypto not installed when loading &#8230;
</p>
</li>
<li>
<p>
Declare caches in Guice rather than hardcoded in Cache&#8230;
</p>
</li>
<li>
<p>
Remove old commented out cache configuration code
</p>
</li>
<li>
<p>
Don&#8217;t NPE in SSH keys panel when SSHD is bound to loca&#8230;
</p>
</li>
<li>
<p>
Don&#8217;t send users to #register,register,mine
</p>
</li>
<li>
<p>
Document the new LDAP support
</p>
</li>
<li>
<p>
Cleanup section anchors to be more useful
</p>
</li>
<li>
<p>
Put anchors on every configuration variable section
</p>
</li>
<li>
<p>
Add missing AOSP copyright header to WebSession
</p>
</li>
<li>
<p>
Fix short header lines in gerrit-config.txt
</p>
</li>
<li>
<p>
Update documentation about system_config private key f&#8230;
</p>
</li>
<li>
<p>
Fetch groups from LDAP during user authentication
</p>
</li>
<li>
<p>
Actually honor cache.ldap_groups.maxage
</p>
</li>
<li>
<p>
Add enum parsing support to ConfigUtil
</p>
</li>
<li>
<p>
Rename LoginType to AuthType
</p>
</li>
<li>
<p>
Support loading the sshUserName from LDAP
</p>
</li>
<li>
<p>
Change ldap.accountDisplayName to ldap.accountFullName
</p>
</li>
<li>
<p>
Fix parsing set-to-nothing options in ldap section
</p>
</li>
<li>
<p>
Report more friendly errors from gwtjsonrpc
</p>
</li>
<li>
<p>
Ensure dialog box displays correctly on network failure
</p>
</li>
<li>
<p>
Document how setting LDAP properties disables web UI
</p>
</li>
<li>
<p>
Ensure the commit body is parsed before getting the co&#8230;
</p>
</li>
<li>
<p>
Cleanup more section anchors
</p>
</li>
<li>
<p>
Make documentation table of contents anchors human rea&#8230;
</p>
</li>
<li>
<p>
Remove notes about HTML 5 offline support
</p>
</li>
<li>
<p>
Fix typo in LegacyGerritServlet javadoc
</p>
</li>
<li>
<p>
Use subList in server side change query code
</p>
</li>
<li>
<p>
Remove unsupported /all_unclaimed
</p>
</li>
<li>
<p>
Rewrite UrlRewriteFilter in terms of Guice bindings
</p>
</li>
<li>
<p>
Create a commit-msg hook to generate Change-Id tags
</p>
</li>
<li>
<p>
Add change_key to changes table in database
</p>
</li>
<li>
<p>
Allow searching for changes by Change-Id strings
</p>
</li>
<li>
<p>
Display the change key, aka Change-ID in the informati&#8230;
</p>
</li>
<li>
<p>
Display abbreviated change ids in change lists
</p>
</li>
<li>
<p>
Change javax.security AccountNotFoundException to NoSu&#8230;
</p>
</li>
<li>
<p>
Automatically update existing changes during refs/for/&#8230;
</p>
</li>
<li>
<p>
Automatically close changes when pushing into a branch&#8230;
</p>
</li>
<li>
<p>
Document the new commit-msg hook supplied by Gerrit
</p>
</li>
<li>
<p>
Correct title of "Command Line Tools" documentation pa&#8230;
</p>
</li>
<li>
<p>
Correct URL example used in Google Analytics Integrati&#8230;
</p>
</li>
<li>
<p>
Correct comment about customizing categories and caches
</p>
</li>
<li>
<p>
Fix formatting of remote.name.timeout section in docum&#8230;
</p>
</li>
<li>
<p>
Add anchors for remote settings in replication.config &#8230;
</p>
</li>
<li>
<p>
Widen the search panel now that Change-Ids are 41 char&#8230;
</p>
</li>
<li>
<p>
Revert "Ensure dialog box displays correctly on networ&#8230;
</p>
</li>
<li>
<p>
Allow searches for Change-Ids starting with lowercase &#8230;
</p>
</li>
<li>
<p>
Fix line wrapped formatting in ChangeListServiceImpl
</p>
</li>
<li>
<p>
Move Change.Key abbreviation to Change.Key class
</p>
</li>
<li>
<p>
Format change ids in listing tables with a fixed with &#8230;
</p>
</li>
<li>
<p>
Cleanup documentation of the commit-msg hook
</p>
</li>
<li>
<p>
Cleanup the command line tool index page
</p>
</li>
<li>
<p>
Correct stale documentation section about SSH authenti&#8230;
</p>
</li>
<li>
<p>
Correct access control documentation about project own&#8230;
</p>
</li>
<li>
<p>
Quote the current directory when running asciidoc
</p>
</li>
<li>
<p>
Move the Default Workflow link into the top of the Use&#8230;
</p>
</li>
<li>
<p>
Correct formatting of usage in gerrit-cherry-pick docu&#8230;
</p>
</li>
<li>
<p>
Document how Gerrit uses Change-Id lines
</p>
</li>
<li>
<p>
Add Change-Id lines during cherry-pick if not already &#8230;
</p>
</li>
<li>
<p>
Fix "no common ancestry" bug
</p>
</li>
<li>
<p>
Fix commit-msg hook to handle first lines like "foo: f&#8230;
</p>
</li>
<li>
<p>
Add a link to Gerrit&#8217;s project to the top of gerrit-ch&#8230;
</p>
</li>
<li>
<p>
Add full ASLv2 copyright notice to commit-msg hook
</p>
</li>
<li>
<p>
Embed Gerrit&#8217;s version number into shell scripts copie&#8230;
</p>
</li>
<li>
<p>
Don&#8217;t drop max_session_age column in transaction durin&#8230;
</p>
</li>
<li>
<p>
gerrit 2.0.19
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Version 2.0.19 (from v2.7-rc2-530-g4d7ac77)<br />
Last updated 2013-10-08 10:02:12 PDT
</div>
</div>
</body>
</html>
